數(shù)據(jù)庫復(fù)制是將數(shù)據(jù)從中央或主服務(wù)器復(fù)制到多個(gè)稱為副本的服務(wù)器的過程。主服務(wù)器接受讀取和寫入操作,而副本服務(wù)器提供只讀事務(wù)。主服務(wù)器和副本共同構(gòu)成一個(gè)數(shù)據(jù)庫集群。數(shù)據(jù)庫復(fù)制的目標(biāo)是確保數(shù)據(jù)的冗余、一致性、高可用性和可訪問性,尤其是在高流量、關(guān)鍵任務(wù)應(yīng)用程序中。
PostgreSQL 提供了兩種復(fù)制方法:物理(即流式)復(fù)制和邏輯復(fù)制。兩者都是不同用例的理想選擇,用戶可以根據(jù)最終目標(biāo)選擇其中之一。讓我們看看這些復(fù)制方法中的每一種。
物理 PostgreSQL 復(fù)制
這是 PostgreSQL 中最常見的復(fù)制類型。物理復(fù)制維護(hù)集群整個(gè)數(shù)據(jù)的完整副本。它使用精確的塊地址并采用逐字節(jié)復(fù)制。簡單來說,主服務(wù)器上的整個(gè)數(shù)據(jù)集都被復(fù)制到充當(dāng)備用節(jié)點(diǎn)的副本。
物理復(fù)制不會(huì)復(fù)制主數(shù)據(jù)庫集群的特定對(duì)象,例如表中的單行數(shù)據(jù)。相反,它在磁盤塊級(jí)別上工作,并將所有數(shù)據(jù)鏡像到副本節(jié)點(diǎn);包括每個(gè)數(shù)據(jù)庫中的所有表。此復(fù)制要求所有副本都相同。
用例:
- 它主要用于災(zāi)難恢復(fù)設(shè)置和備份,因?yàn)樗懈北径际窍嗤摹?/li>
- 處理大量數(shù)據(jù)時(shí)推薦使用
優(yōu)點(diǎn)
- 它很容易實(shí)現(xiàn),因?yàn)樗械臄?shù)據(jù)庫集群都是相同的。
- 它確保了任何時(shí)候的數(shù)據(jù)一致性和高可用性,因?yàn)樗懈北径汲钟邢嗤臄?shù)據(jù)副本。
- 它非常適合對(duì)副本進(jìn)行只讀操作。
- 它非常高效,因?yàn)樗恍枰魏翁厥馓幚怼?/li>
缺點(diǎn)
- 這是帶寬密集型的,因?yàn)橐獜?fù)制整個(gè)數(shù)據(jù),而不僅僅是主集群的一小部分。
- 它不提供多主數(shù)據(jù)庫復(fù)制。
邏輯 PostgreSQL 復(fù)制
邏輯復(fù)制最早是在 PostgreSQL 9.0 中引入的。它通過復(fù)制數(shù)據(jù)對(duì)象及其基于唯一標(biāo)識(shí)符(如主鍵)的更改來工作。簡單來說,邏輯復(fù)制以基于行的模型復(fù)制數(shù)據(jù)庫對(duì)象,而不是將所有內(nèi)容發(fā)送到副本節(jié)點(diǎn)的物理復(fù)制。
因此,與物理復(fù)制相反,邏輯復(fù)制提供了對(duì)數(shù)據(jù)復(fù)制的細(xì)粒度控制。
用例:
邏輯復(fù)制的典型用例包括:
- 在不同主要版本的 PostgreSQL 之間復(fù)制。
- 在不同平臺(tái)上托管的 PostgreSQL 實(shí)例之間進(jìn)行復(fù)制,例如從 Linux 到 Windows。
- 將數(shù)據(jù)庫中的增量更改實(shí)時(shí)發(fā)送到副本。
- 向不同的用戶組授予對(duì)復(fù)制數(shù)據(jù)的訪問權(quán)限。
優(yōu)點(diǎn)
- 它是備份增量數(shù)據(jù)的理想選擇。
- 由于更好的性能和低數(shù)據(jù)丟失,最推薦用于高可用性集群。
- 帶寬優(yōu)化,因?yàn)橹挥刑峤坏臄?shù)據(jù)事務(wù)的行更改才會(huì)發(fā)送到副本,而不是整個(gè)數(shù)據(jù)塊。
- 用于使用物理復(fù)制無法實(shí)現(xiàn)的多主復(fù)制。
- 支持跨各種操作系統(tǒng)平臺(tái)的復(fù)制,例如 Linux 到 Windows,反之亦然。
缺點(diǎn)
- 它無法實(shí)時(shí)傳輸大量交易。
- 復(fù)制過程比物理復(fù)制更復(fù)雜。
- 副本節(jié)點(diǎn)上的資源利用率高。
在 Ubuntu 22.04 上設(shè)置物理 PostgreSQL 復(fù)制
為了演示復(fù)制過程,您需要一個(gè)主節(jié)點(diǎn)和一個(gè)將在其上進(jìn)行復(fù)制的副本節(jié)點(diǎn)。下面是我們的實(shí)驗(yàn)室設(shè)置,我們將使用 Ubuntu 22.04 作為首選操作系統(tǒng)。
主節(jié)點(diǎn):IP:194.195.208.82 操作系統(tǒng):Ubuntu 22.04 服務(wù)器
副本節(jié)點(diǎn):IP:139.144.169.79 操作系統(tǒng):Ubuntu 22.04 服務(wù)器
第 1 步:安裝 PostgreSQL 服務(wù)器
第一步是在主節(jié)點(diǎn)和副本節(jié)點(diǎn)上安裝 PostgreSQL。請(qǐng)注意,您需要在兩個(gè)節(jié)點(diǎn)上安裝相同版本的 PostgreSQL 才能進(jìn)行邏輯復(fù)制。
在撰寫本指南時(shí),最新版本的 PostgreSQL 是 PostgreSQL 14。
首先,通過 SSH 登錄到您的服務(wù)器并刷新存儲(chǔ)庫。
sudo apt update
接下來,按如下方式安裝 PostgreSQL 數(shù)據(jù)庫服務(wù)器。
sudo apt install postgresql postgresql-contrib -y
默認(rèn)情況下,PostgreSQL 守護(hù)程序會(huì)在安裝后自動(dòng)運(yùn)行。您可以使用以下命令驗(yàn)證這一點(diǎn):
sudo systemctl status postgresql
下面的輸出確認(rèn) PostgreSQL 服務(wù)已啟動(dòng)并正在運(yùn)行。
此外,考慮使服務(wù)在系統(tǒng)啟動(dòng)時(shí)啟動(dòng),如下所示。
sudo systemctl enable postgresql
第二步:配置主節(jié)點(diǎn)
接下來,以用戶身份登錄主節(jié)點(diǎn) (194.195.208.82),postgres該用戶是每次新安裝 PostgreSQL 時(shí)創(chuàng)建的默認(rèn)用戶。
sudo -u postgres psql
您需要?jiǎng)?chuàng)建一個(gè)復(fù)制用戶,用于從主節(jié)點(diǎn)啟動(dòng)復(fù)制過程。
因此,運(yùn)行以下命令創(chuàng)建復(fù)制用戶并分配復(fù)制權(quán)限。在此命令中,replica_user?是復(fù)制用戶,而P@ssword321是用戶的密碼。請(qǐng)務(wù)必提供一個(gè)強(qiáng)密碼,這與我們使用的純粹用于演示目的的密碼不同。
CREATE ROLE replica_user WITH REPLICATION LOGIN PASSWORD 'P@ssword321';
然后從 PostgreSQL 提示符注銷
postgres-# \q
接下來,您需要對(duì)主配置文件進(jìn)行一些調(diào)整。使用您喜歡的文本編輯器訪問以下配置文件:
sudo vim /etc/postgresql/14/main/postgresql.conf
打開文件后,向下滾動(dòng)并找到該listen_addresses指令。該指令指定 PostgreSQL 數(shù)據(jù)庫服務(wù)器偵聽連接的主機(jī)。
通過刪除#符號(hào)取消注釋該指令,并替換localhost為用單引號(hào)括起來的服務(wù)器 IP 地址,如下所示:
接下來,找到該wal_level指令。該設(shè)置指定要寫入預(yù)寫日志 (WAL) 文件的信息量。
取消注釋該行并將其設(shè)置logical為如圖所示。
接下來,找到該wal_log_hints指令。默認(rèn)情況下,它設(shè)置為off。
當(dāng)設(shè)置on為該值時(shí),允許 PostgreSQL 服務(wù)器在頁面的第一次修改期間將每個(gè)磁盤頁面的全部內(nèi)容寫入 WAL 文件。
取消注釋并將其設(shè)置為on.
這就是此配置文件中所需更改的全部內(nèi)容。保存更改并退出。
接下來,訪問/etc/postgresql/14/main/pg_hba.conf配置文件。
sudo vim /etc/postgresql/14/main/pg_hba.conf
將此行附加到配置文件的末尾。這允許副本 (139.144.169.79) 使用replica_user.
host replication replica_user 139.144.169.79/24 md5
保存更改并關(guān)閉文件。重啟 PostgreSQL 服務(wù)。
sudo systemctl restart postgresql
第三步:配置副本節(jié)點(diǎn)
在副本節(jié)點(diǎn)可以開始從主節(jié)點(diǎn)復(fù)制數(shù)據(jù)之前,您需要?jiǎng)?chuàng)建主節(jié)點(diǎn)數(shù)據(jù)目錄到副本數(shù)據(jù)目錄的副本。為此,首先,停止副本節(jié)點(diǎn)上的 PostgreSQL 服務(wù)。
sudo systemctl stop postgresql
接下來,刪除副本數(shù)據(jù)目錄中的所有文件,以便從頭開始并為主節(jié)點(diǎn)數(shù)據(jù)目錄騰出空間。
sudo rm -rv /var/lib/postgresql/14/main/
現(xiàn)在pg_basebackup?如圖所示運(yùn)行該實(shí)用程序,將數(shù)據(jù)從主節(jié)點(diǎn)復(fù)制到副本節(jié)點(diǎn)。
sudo pg_basebackup -h 194.195.208.82 -U replica_user -X stream -C -S replica_1 -v -R -W -D /var/lib/postgresql/14/main/
讓我們看一下命令中使用的選項(xiàng):
- -h:此選項(xiàng)指定主機(jī),在本例中為主節(jié)點(diǎn)的 IP 地址。
- -U:該選項(xiàng)指定復(fù)制用戶。這是在主節(jié)點(diǎn)上配置的用戶,副本節(jié)點(diǎn)將使用該用戶連接到它。在我們的例子中,復(fù)制用戶被稱為replica_user.
- -X:該選項(xiàng)與流值一起指示pg_basebackup實(shí)用程序流式傳輸并將 WAL 文件包含在備份中。
- -C:該選項(xiàng)允許您在備份開始之前創(chuàng)建一個(gè)復(fù)制槽。該選項(xiàng)與-S指定插槽名稱的選項(xiàng)一起使用。在這種情況下,我們的復(fù)制槽稱為replica_1。
- -v:這會(huì)打印出詳細(xì)的輸出,指示從主節(jié)點(diǎn)到副本的備份過程的進(jìn)度。
- -R:該選項(xiàng)創(chuàng)建兩個(gè)文件;一個(gè)名為的空恢復(fù)配置文件standby.signal和一個(gè)名為的主節(jié)點(diǎn)連接設(shè)置文件postgresql.auto.conf.該standby.signal文件包含有關(guān)主節(jié)點(diǎn)的連接信息,該postgresql.auto.conf?文件通知您的副本集群它應(yīng)該作為備用服務(wù)器運(yùn)行。
- -W:這會(huì)提示您為replica_user?復(fù)制用戶提供密碼。
- -D:最后,該-D選項(xiàng)允許您包含要導(dǎo)出備份文件的目錄。在這個(gè)例子中,我們將數(shù)據(jù)放在/var/lib/postgresql/14/main/副本節(jié)點(diǎn)的目錄下。
這是運(yùn)行復(fù)制命令的輸出。
之后,在副本上執(zhí)行以下命令以將數(shù)據(jù)目錄的所有權(quán)授予 postgres 用戶。
sudo chown postgres -R /var/lib/postgresql/14/main/
現(xiàn)在,啟動(dòng) PostgreSQL 服務(wù)器。副本現(xiàn)在將以熱備用模式運(yùn)行。
sudo systemctl start postgresql
第 4 步:測(cè)試復(fù)制設(shè)置
至此,主節(jié)點(diǎn)的數(shù)據(jù)目錄已經(jīng)成功備份到副本上,副本開始雙機(jī)熱備。
剩下的部分是測(cè)試復(fù)制是否按預(yù)期工作。如果副本在熱備模式下成功運(yùn)行,那么它應(yīng)該連接到主服務(wù)器上的主數(shù)據(jù)庫集群。
要驗(yàn)證副本是否連接到主節(jié)點(diǎn)并且主節(jié)點(diǎn)正在流式傳輸,請(qǐng)登錄到主服務(wù)器并切換到postgres?用戶。
sudo -u postgres psql
接下來,查詢pg_stat_replication包含有關(guān)復(fù)制的重要信息的表。在此命令中,我們正在檢索有關(guān)副本的 IP 地址和主服務(wù)器狀態(tài)的信息。
SELECT client_addr, state FROM pg_stat_replication;
您應(yīng)該得到以下輸出確認(rèn)您的設(shè)置正在運(yùn)行。
為了證實(shí)這一點(diǎn),我們將創(chuàng)建一個(gè)測(cè)試數(shù)據(jù)庫并添加一個(gè)包含幾條記錄的表,然后驗(yàn)證數(shù)據(jù)庫是否已在副本上復(fù)制。
我們將創(chuàng)建一個(gè)名為students.
CREATE DATABASE students_db;
接下來,切換到數(shù)據(jù)庫。
\c students_db;
輸出
You are now connected to database "students_db" as user "postgres".
進(jìn)入數(shù)據(jù)庫后,創(chuàng)建一個(gè)student_details使用以下模式調(diào)用的表。
CREATE TABLE student_details (first_name VARCHAR(15), last_name VARCHAR(15) , email VARCHAR(40) );
然后將以下記錄插入表中。
INSERT INTO student_details (first_name, last_name, email) VALUES ('Arthur', 'Spencer', 'arthurspencer@gmail.com');
您可以查詢表以確認(rèn)插入的記錄,如圖所示。
SELECT * FROM student_details;
現(xiàn)在轉(zhuǎn)到副本節(jié)點(diǎn)并切換到postgres?用戶。
sudo -u postgres psql
在 shell 上,驗(yàn)證剛才在主節(jié)點(diǎn)中創(chuàng)建的數(shù)據(jù)庫是否存在。
postgres=# \l
現(xiàn)在,切換到數(shù)據(jù)庫。
\c students_db;
查詢表中存儲(chǔ)的所有記錄。
SELECT * FROM student_details;
您應(yīng)該得到與您在主節(jié)點(diǎn)中創(chuàng)建的記錄完全相同的記錄,如下所示。
這就證明復(fù)制成功了!您可以繼續(xù)在主服務(wù)器上添加更多記錄,然后將這些記錄復(fù)制或復(fù)制到副本節(jié)點(diǎn)。
結(jié)論
在本教程中,我們了解了 PostgreSQL 提供的兩種復(fù)制方法及其優(yōu)缺點(diǎn)。我們更進(jìn)一步,使用 PostgreSQL 邏輯模型創(chuàng)建了一個(gè)復(fù)制集群,并演示了從主節(jié)點(diǎn)到副本節(jié)點(diǎn)的數(shù)據(jù)復(fù)制。前往官方文檔以更全面地了解 PostgreSQL 中的復(fù)制。